﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Web;
using System.Xml.Linq;
using System.Net.Mail;
using NHibernate.Cfg;
using NHibernate;
using NHibernate.Tool.hbm2ddl;
using NHibernate.Criterion;

namespace KinozalTVMonitor
{
    class Program
    {
        static void Main(string[] args)
        {
            DatabaseConfigure();

            try
            {
                XDocument cfg = XDocument.Load("keyword.config");
                foreach (XElement keywordElement in cfg.Root.Elements("keyword"))
                {
                    ProcessKeyword(keywordElement.Value);
                }
            }
            catch (Exception ex)
            {
                SendExceptionMail(ex);
            }
        }

        private static void ProcessKeyword(string keyword)
        {
            WebClient kinozal = new WebClient();
            string searchKey = HttpUtility.UrlEncode(keyword, Encoding.GetEncoding("windows-1251"));
            string url = "http://kinozal.tv/browse.php?s=" + searchKey;
            string html = kinozal.DownloadString(url);
            string begin = @"Раздает</a></td></tr>";
            html = html.Remove(0, html.IndexOf(begin) + begin.Length + 1);
            html = html.Remove(html.IndexOf("</tr>") + 5);

            string pubDateBegin = "<td align=center nowrap><small>";
            int pdsi = html.IndexOf(pubDateBegin) + pubDateBegin.Length;
            int pdei = html.IndexOf("<br>", pdsi);
            string pubDateSring = html.Substring(pdsi, pdei - pdsi).Trim();
            DateTime pubDate = DateTime.MinValue;
            if (pubDateSring.Equals("сегодня", StringComparison.InvariantCultureIgnoreCase)) pubDate = DateTime.Now.Date;
            else if (pubDateSring.Equals("вчера", StringComparison.InvariantCultureIgnoreCase)) pubDate = (DateTime.Now - TimeSpan.FromDays(1)).Date;
            else pubDate = DateTime.Parse(pubDateSring);

            pdsi = pdei + "<br>".Length + 1;
            pdei = html.IndexOf("</small>", pdsi);
            string pubTimeString = html.Substring(pdsi, pdei - pdsi);
            pubDate += TimeSpan.Parse(pubTimeString);

            WebEvent we = GetEvent(keyword);
            if (we.PublishDate == pubDate) return;

            SmtpClient mail = GetMailClient();
            MailMessage msg = GetMailMessage();
            msg.IsBodyHtml = true;
            msg.Body = "<table>" + html + "</table>";
            msg.Body = msg.Body.Replace("a href=/", "a href=http://kinozal.tv/");
            msg.Body = msg.Body.Replace("a href='/", "a href='http://kinozal.tv/");
            msg.Subject = "Kinozal.TV Event";
            mail.Send(msg);

            SaveEvent(keyword, pubDate);
        }

        private static void SendExceptionMail(Exception exception)
        {
            SmtpClient mail = GetMailClient();
            MailMessage msg = GetMailMessage();
            msg.Body = exception.Message + "\n\n" + exception.StackTrace;
            msg.Subject = "Kinozal.TV Exception";
            mail.Send(msg);
        }

        private static SmtpClient GetMailClient()
        {
            SmtpClient mail = new SmtpClient("smtp.mail.ru", 587);
            mail.Credentials = new NetworkCredential { UserName = "robot@mailserver.com", Password = "*******" };
            return mail;
        }

        private static MailMessage GetMailMessage()
        {
            MailAddress from = new MailAddress("simede@mail.ru", "Mazatec Robot");
            return new MailMessage(from, new MailAddress("your@gmail.com"));
        }

        private static ISessionFactory SessionFactory;
        private static void DatabaseConfigure()
        {
            Configuration cfg = new Configuration();
            cfg.Configure();

            //SchemaExport se = new SchemaExport(cfg);
            //se.Create(false, true);

            SessionFactory = cfg.BuildSessionFactory();
        }

        private static WebEvent GetEvent(string keyword)
        {
            ISession session = SessionFactory.OpenSession();
            ITransaction transaction = session.BeginTransaction();
            WebEvent we = (WebEvent)session.Get(typeof(WebEvent), keyword);
            if (we == null)
            {
                we = new WebEvent { Keyword = keyword, PublishDate = DateTime.MinValue };
                session.Save(we);
            }
            //IList list = session.CreateCriteria(typeof(WebEvent)).Add(Expression.e("Title", "Москва", MatchMode.Anywhere)).List();
            transaction.Commit();
            session.Close();
            return we;
        }

        private static void SaveEvent(string keyword, DateTime pubDate)
        {
            ISession session = SessionFactory.OpenSession();
            ITransaction transaction = session.BeginTransaction();
            WebEvent we = (WebEvent)session.Get(typeof(WebEvent), keyword);
            if (we == null)
            {
                we = new WebEvent { Keyword = keyword };
            }
            we.PublishDate = pubDate;
            session.SaveOrUpdate(we);
            transaction.Commit();
            session.Close();
        }
    }
}